package com.sunda.spmsorder.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmscommon.feign.IFeignServiceCommon;
import com.sunda.spmscommon.service.ISysLogService;
import com.sunda.spmsorder.entity.MaterialSap;
import com.sunda.spmsorder.entity.MaterialSapWerksRelation;
import com.sunda.spmsorder.mapper.MaterialSapMapper;
import com.sunda.spmsorder.mapper.MaterialSrmLongContractMapper;
import com.sunda.spmsorder.service.IMaterialSapService;
import com.sunda.spmsorder.service.IMaterialSapWerksRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.sunda.spmscommon.Constans.MATERIAL_UPDATE_REAL_TIME;

/**
 * <p>
 * 物料表SAP 服务实现类
 * </p>
 *
 * @author Wayne
 * @since 2020-12-09
 */
@Service
public class MaterialSapServiceImpl extends ServiceImpl<MaterialSapMapper, MaterialSap> implements IMaterialSapService {

    @Autowired
    MaterialSapMapper materialSapMapper;

    @Autowired
    MaterialSrmLongContractMapper materialSrmLongContractMapper;

    @Autowired
    IMaterialSapWerksRelationService iMaterialSapWerksRelationService;

    @Autowired
    IFeignServiceCommon iFeignServiceCommon;

    @Autowired
    ISysLogService iSysLogService;

    /** 查询 material_sap 表指定数据，及关联目录信息，贸易货，备件货 */
    @Override
    public ResponseResult getMaterialSapXM(String materialNo) {
        if(StringUtils.isEmpty(materialNo)){
            ResponseResult.error("Material No is mandatory required");
        }
        return ResponseResult.success().add("materialList",materialSapMapper.selectList(new QueryWrapper<MaterialSap>().eq("MATERIAL_NO", materialNo)));
    }

    /**
     * 根据物料编号查询指定物料所属目录信息；如果目录信息为空则返回该物料详细信息；如果物料参数传空则返回所有没有目录信息的物料信息；
     * @param materialNo
     * @return
     */
    @Override
    public ResponseResult getMaterialSap(String materialNo, int pageNo, int pageSize) {
        if(StringUtils.isEmpty(materialNo)){
            PageHelper.startPage(pageNo, pageSize);
            List<Map<String, Object>> mapList = materialSapMapper.getNonCategoryMaterialSap();
            return ResponseResult.success().add("materialSapList", mapListToPageMap(mapList));
        }
        List<Map<String,Object>> mapList = materialSapMapper.getCategoryByMaterialSap(materialNo);
        if (mapList.size() > 0){
            return ResponseResult.success().add("materialCategoryList", mapListToPageMap(mapList));
        }
        MaterialSap materialSap=materialSapMapper.selectOne(new QueryWrapper<MaterialSap>().eq("MATERIAL_NO", materialNo));
        return ResponseResult.success().add("material", materialSap);
    }

    /** 根据多物料编码精确查询 或 物料描述模糊查询物料信息数据，包含物料长协信息 */
    @Override
    public Map<String, Object> searchMaterialSap(int pageNo, int pageSize, String categoryId, String materialNoList, String materialZhDesc, String materialEnDesc,String productLevelSmallDesc,String specs,String brand) {
        List<String> list = new ArrayList<>();
        if (materialNoList.trim().length() > 0){
            String[] array = materialNoList.trim().split(",");
            for (int i = 0; i < array.length; i++){
                list.add(array[i]);
            }
        }
        /** 空数组或空字符串，传给 Mapper 都要转换为 null */
        list = list.size() == 0 ? null : list;
        categoryId = categoryId.trim().length() == 0 ? null : categoryId.trim();
        materialZhDesc = materialZhDesc.replaceAll("^[　 ]+|[　 ]+$","") == "" ? null : materialZhDesc.replaceAll("^[　 ]+|[　 ]+$","");
        materialEnDesc = materialEnDesc.replaceAll("^[　 ]+|[　 ]+$","") == "" ? null : materialEnDesc.replaceAll("^[　 ]+|[　 ]+$","");
        productLevelSmallDesc=productLevelSmallDesc.equals("")?null:productLevelSmallDesc.toUpperCase().trim();
        specs=specs.equals("")?null:specs.toUpperCase().trim();
        brand=brand.equals("")?null:brand.toUpperCase().trim();
        PageHelper.startPage(pageNo, pageSize);
        List<Map<String, Object>> mapList = materialSapMapper.searchMaterialSap(categoryId, list, materialZhDesc, materialEnDesc,productLevelSmallDesc,specs,brand);
//        for (Map<String, Object> map: mapList) {
//            map.put("materialSrmSourceList", materialSrmLongContractMapper.selectList(
//                    new QueryWrapper<MaterialSrmLongContract>().eq("MATERIAL_NO", map.get("materialNo"))));
//        }
        return mapListToPageMap(mapList);
    }


    /** 根据多物料编码精确查询 或 物料描述模糊查询物料信息数据，不包含物料长协信息 */
    @Override
    public Map<String, Object> searchMaterialSapNoContract(int pageNo, int pageSize, String categoryId, String materialNoList, String materialZhDesc, String materialEnDesc,String productLevelDesc,String specs,String brand) {
        List<String> list = new ArrayList<>();
        if (materialNoList.trim().length() > 0){
            String[] array = materialNoList.trim().split(",");
            for (int i = 0; i < array.length; i++){
                list.add(array[i]);
            }
        }
        /** 空数组或空字符串，传给 Mapper 都要转换为 null */
        list = list.size() == 0 ? null : list;
        categoryId = categoryId.trim().length() == 0 ? null : categoryId.trim();
        materialZhDesc = materialZhDesc.replaceAll("^[　 ]+|[　 ]+$","") == "" ? null : materialZhDesc.replaceAll("^[　 ]+|[　 ]+$","");
        materialEnDesc = materialEnDesc.replaceAll("^[　 ]+|[　 ]+$","") == "" ? null : materialEnDesc.replaceAll("^[　 ]+|[　 ]+$","");
        productLevelDesc=productLevelDesc.equals("")?null:productLevelDesc.toUpperCase().trim();
        specs=specs.equals("")?null:specs.toUpperCase().trim();
        brand=brand.equals("")?null:brand.toUpperCase().trim();
        PageHelper.startPage(pageNo, pageSize);

        List<Map<String, Object>> mapList = materialSapMapper.searchMaterialSap(categoryId, list, materialZhDesc, materialEnDesc,productLevelDesc,specs,brand);

        return mapListToPageMap(mapList);
    }

    /** 根据多物料编码精确查询 或 物料描述模糊查询物料信息数据，不包含物料长协信息 */
    @Override
    public Map<String, Object> searchMaterialSapNoContractGlobal(int pageNo, int pageSize, String keyword) {
        keyword = keyword.replaceAll("^[　 ]+|[　 ]+$","") == "" ? null : keyword.replaceAll("^[　 ]+|[　 ]+$","");
        PageHelper.startPage(pageNo, pageSize);

        List<Map<String, Object>> mapList = materialSapMapper.searchMaterialSapGlobal(keyword);

        return mapListToPageMap(mapList);
    }

    /** 根据多物料编码精确查询 或 物料描述模糊查询物料信息数据，包含对应工厂下库存信息，不包含物料长协信息 */
    @Override
    public Map<String, Object> getMaterialSapInventory(int pageNo, int pageSize, String werks, String whsStr, String categoryId, String materialNoList, String materialZhDesc, String materialEnDesc,String productLevelDesc,String specs,String brand) {
        List<String> materialList = new ArrayList<>();
        if (materialNoList.trim().length() > 0){
            String[] array = materialNoList.trim().split(",");
            for (int i = 0; i < array.length; i++){
                materialList.add(array[i]);
            }
        }
        List<String> whsList = new ArrayList<>();
        if (whsStr.trim().length() > 0){
            String [] arr = whsStr.trim().split(",");
            for (int i = 0; i < arr.length; i++){
                whsList.add(arr[i]);
            }
        }
        /** 空数组或空字符串，传给 Mapper 都要转换为 null */
        werks = werks.trim();
        materialList = materialList.size() == 0 ? null : materialList;
        whsList = whsList.size() == 0 ? null : whsList;
        categoryId = categoryId.trim().length() == 0 ? null : categoryId.trim();
        materialZhDesc = materialZhDesc.replaceAll("^[　 ]+|[　 ]+$","") == "" ? null : materialZhDesc.replaceAll("^[　 ]+|[　 ]+$","");
        materialEnDesc = materialEnDesc.replaceAll("^[　 ]+|[　 ]+$","") == "" ? null : materialEnDesc.replaceAll("^[　 ]+|[　 ]+$","");
        productLevelDesc=productLevelDesc.equals("")?null:productLevelDesc.toUpperCase().trim();
        specs=specs.equals("")?null:specs.toUpperCase().trim();
        brand=brand.equals("")?null:brand.toUpperCase().trim();
        PageHelper.startPage(pageNo, pageSize);
        List<Map<String, Object>> mapList = materialSapMapper.getMaterialSapInventory(werks, whsList, categoryId, materialList, materialZhDesc, materialEnDesc);
        return mapListToPageMap(mapList);
    }

    /** 根据多物料编码精确查询 或 物料描述模糊查询物料信息数据，包含对应工厂下库存信息，包含物料长协信息 */
    @Override
    public Map<String, Object> getMaterialSapInventoryInfo(int pageNo, int pageSize, String werks, String categoryId, String materialNoList, String materialZhDesc, String materialEnDesc,String productLevelDesc,String specs,String brand) {
        List<String> list = new ArrayList<>();
        if (materialNoList.trim().length() > 0){
            String[] array = materialNoList.trim().split(",");
            for (int i = 0; i < array.length; i++){
                list.add(array[i]);
            }
        }
        /** 空数组或空字符串，传给 Mapper 都要转换为 null */
        werks = werks.trim();
        list = list.size() == 0 ? null : list;
        categoryId = categoryId.trim().length() == 0 ? null : categoryId.trim();
        materialZhDesc = materialZhDesc.replaceAll("^[　 ]+|[　 ]+$","") == "" ? null : materialZhDesc.replaceAll("^[　 ]+|[　 ]+$","");
        materialEnDesc = materialEnDesc.replaceAll("^[　 ]+|[　 ]+$","") == "" ? null : materialEnDesc.replaceAll("^[　 ]+|[　 ]+$","");
        productLevelDesc=productLevelDesc.equals("")?null:productLevelDesc.toUpperCase().trim();
        specs=specs.equals("")?null:specs.toUpperCase().trim();
        brand=brand.equals("")?null:brand.toUpperCase().trim();
        PageHelper.startPage(pageNo, pageSize);
        List<Map<String, Object>> mapList = materialSapMapper.searchMaterialSap(categoryId, list, materialZhDesc, materialEnDesc,productLevelDesc,specs,brand);
        for (Map<String, Object> map: mapList) {
            map.put("materialInventoryList",
                    materialSapMapper.getMaterialInventory(werks, map.get("materialNo").toString()));
//            map.put("materialSrmSourceList",
//                    materialSrmLongContractMapper.getByMaterialNo(map.get("materialNo").toString()));
        }
        return mapListToPageMap(mapList);
    }


    public Map<String,Object> mapListToPageMap(List<Map<String, Object>> mapList){
        PageInfo<Map<String, Object>> pageData = new PageInfo<>(mapList);
        Map<String,Object> pageInfo = new HashMap<>();
        pageInfo.put("records", pageData.getList());
        pageInfo.put("total", pageData.getTotal());
        pageInfo.put("size", pageData.getSize());
        pageInfo.put("current", pageData.getPageNum());
        pageInfo.put("pages", pageData.getPages());
        return pageInfo;
    }

    @Override
    public ResponseResult getMaterialDataFromSap(String dataDate, String userId) {
        try {
            if (StringUtils.isEmpty(dataDate)){
                return ResponseResult.error("请求参数错误请重试");
            }
            JSONObject dataToSap = formatDataToSap(dataDate);
            String message = iFeignServiceCommon.sendRestToSapCommon(dataToSap);
            JSONObject doc = JSONObject.parseObject(message);
            JSONArray respArray = new JSONArray();
            if (doc.containsKey("RESPONSE") && doc.getJSONObject("RESPONSE").containsKey("RETURN_DATA")){
                JSONObject RETURN_DATA = doc.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
                if (RETURN_DATA.containsKey("O_TYPE") && "S".equals(RETURN_DATA.getString("O_TYPE"))){
                    JSONArray Z_SPMS_GETSKUDATA_IT_MARA = RETURN_DATA.getJSONObject("DATA").getJSONArray("Z_SPMS_GETSKUDATA_IT_MARA");
                    respArray = insertMaterialSap(Z_SPMS_GETSKUDATA_IT_MARA);

                    //JSONArray Z_SPMS_GETSKUDATA_IT_MARC = RETURN_DATA.getJSONObject("DATA").getJSONArray("Z_SPMS_GETSKUDATA_IT_MARC");
                    //insertMaterialSapWerksRelation(Z_SPMS_GETSKUDATA_IT_MARC);
                    /** SPMS暂不考虑物料工厂关系，这些数据忽略更新 ———— Wayne 20210922 */

                    addRestSapLog(respArray, dataToSap, userId);
                    /** 记录用户操作日志，返回更新料号列表；错误则返回错误信息； */
                    return ResponseResult.success().add("updatedData", respArray).add("dataToSap", dataToSap);
                }
            }
            return ResponseResult.error().add("sapReturnedData", doc).add("dataToSap", dataToSap);

        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("请求过程出错");
        }
    }

    JSONObject formatDataToSap(String dataDate){
        JSONObject dataToSap = new JSONObject();
        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();
        JSONObject Head = new JSONObject();

        Head.put("iDate", dataDate.replaceAll("-", ""));
        REQUEST_DATA.put("Head", Head);
        REQUEST_DATA.put("Operation", "Z_SPMS_GETSKUDATA");
        REQUEST_DATA.put("Type", "Z_SPMS_GETSKUDATA");
        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());
        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);
        dataToSap.put("REQUEST", REQUEST);
        return dataToSap;
    }

    JSONArray insertMaterialSap(JSONArray array){
        JSONArray jsonArray = new JSONArray();
        try {
            for(int i = 0; i < array.size(); i++) {
                System.out.println("=======" + array.size() + "    " + i + "   SAP 物料信息  " + array.get(i).toString());
                if (i > 0) {  // i = 0 时存的是表头信息
                    JSONArray json = JSONArray.parseArray(array.get(i).toString());
                    jsonArray.add(json.getString(0));
                    MaterialSap materialSap = new MaterialSap();
                    materialSap.setMaterialNo(json.getString(0));
                    materialSap.setMaterialZhDesc(json.getString(1));
                    materialSap.setSpmsMark(json.getString(22));
                    materialSap.setMaterialEnDesc(json.getString(2));
                    materialSap.setProductLevelLarge(json.getString(4));
                    materialSap.setProductLevelLargeDesc(json.getString(5));
                    materialSap.setProductLevelMid(json.getString(6));
                    materialSap.setProductLevelMidDesc(json.getString(7));
                    materialSap.setProductLevelSmall(json.getString(8));
                    materialSap.setProductLevelSmallDesc(json.getString(9));
                    materialSap.setProductLevel(json.getString(29));
                    materialSap.setProductLevelDesc(json.getString(30));
                    materialSap.setMaterialName(json.getString(23));
                    materialSap.setSpecs(json.getString(24));
                    materialSap.setMaterialModel(json.getString(25));
                    materialSap.setSupplyDesc(json.getString(26));
                    materialSap.setBrand(json.getString(27));
                    materialSap.setSupplierMaterialNo(json.getString(28));
                    materialSap.setBasicUnit(json.getString(11));
                    materialSap.setPurchaseUnit(json.getString(12));
                    materialSap.setNetWeight(json.getString(13));
                    materialSap.setGrossWeight(json.getString(14));
                    materialSap.setWeightUnit(json.getString(15));
                    materialSap.setVolumeQty(json.getString(16));
                    materialSap.setVolumeUnit(json.getString(17));
                    materialSap.setLightHeavyMark(json.getString(18));
                    materialSap.setIsDelete(json.getString(19));
                    materialSap.setMaterialStatus(json.getString(20));
                    materialSap.setCreateDate(json.getString(21));
                    materialSap.setUnitSales(json.getString(33));
                    materialSap.setNumerator(StringUtils.isEmpty(json.getString(32)) ? 1 : json.getDoubleValue(32));
                    materialSap.setDenominator(StringUtils.isEmpty(json.getString(31)) ? 1 : json.getDoubleValue(31));
                    materialSap.setMaterialStandard(json.getString(34));
                    materialSap.setPurchaseGroup(json.getString(35));
                    materialSap.setPurchaseGroupDesc(json.getString(36));
                    materialSap.setOnMall(json.getString(37));
                    materialSap.setMovementType(json.getString(38));
                    materialSap.setReservedField(json.getString(39));
                    materialSap.setProductAddress(json.getString(40));
                    materialSap.setOrderCode(json.getString(41));
                    /** 直接按照新数据写入数据库，重复数据由数据库触发器自动删除 - 20210527 */
                    materialSapMapper.insert(materialSap);
                }
            }
            return jsonArray;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    void insertMaterialSapWerksRelation(JSONArray array){
        try {
            for(int i = 0; i < array.size(); i++) {
                System.out.println("=======" + array.size() + "    " + i + "   SAP 物料工厂关系数据  " + array.get(i).toString());
                if (i > 0) {  // i = 0 时存的是表头信息
                    JSONArray json = JSONArray.parseArray(array.get(i).toString());
                    MaterialSapWerksRelation materialSapWerksRelation = new MaterialSapWerksRelation();

                    materialSapWerksRelation.setMaterialNo(json.getString(0));
                    materialSapWerksRelation.setWerks(json.getString(1));
                    materialSapWerksRelation.setIsDelete(json.getString(2));
                    materialSapWerksRelation.setMaterialStatus(json.getString(3));

                    /** 直接按照新数据写入数据库，重复数据由数据库触发器自动删除 - 20210427 */
                    iMaterialSapWerksRelationService.insertMaterialWerksRelation(materialSapWerksRelation);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /** 日志类型（1操作日志，2登录日志，3提交OA记录，4请求SAP日志） */
    void addRestSapLog(JSONArray respArray, JSONObject doc, String userId){
        iSysLogService.spmsRestToSap("4", MATERIAL_UPDATE_REAL_TIME, "修改", userId,
                "com.sunda.spmsweb.ordercontroller.getMaterialDataFromSap()", doc.toJSONString(),
                "REST", respArray.toJSONString());
    }

    /**
     {
     "userId": "999947",
     "beginDate": "",
     "endDate": "",
     "pageNo": "1",
     "pageSize": "20"
     }
     * @param doc
     * @return
     */
    @Override
    public ResponseResult getMaterialDataFromSapRecord(JSONObject doc) {
        try {
            String userId = StringUtils.isEmpty(doc.getString("userId")) ? null : doc.getString("userId");
            String beginDate = StringUtils.isEmpty(doc.getString("userId")) ? null : doc.getString("userId");
            String endDate = StringUtils.isEmpty(doc.getString("userId")) ? null : doc.getString("userId");
            int pageNo = StringUtils.isEmpty(doc.getString("pageNo")) ? 1 : doc.getInteger("pageNo");
            int pageSize = StringUtils.isEmpty(doc.getString("pageSize")) ? 20 : doc.getInteger("pageSize");
            Page<Map<String, Object>> pages = new Page<>(pageNo, pageSize);
            List<Map<String, Object>> pageMaData = this.baseMapper.getOperateLog(pages, userId, beginDate, endDate);
            pages.setRecords(pageMaData);
            return ResponseResult.success().add("getMaterialDataFromSapRecord", pages);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("请求执行错误");
        }
    }

    @Override
    public ResponseResult getAllMaterialX() {
        return ResponseResult.success().add("getAllMaterialX", this.baseMapper.getAllMaterialX());
    }

    @Override
    public MaterialSap getMaterialInfo(String materialNo) {
        return this.baseMapper.selectOne(new QueryWrapper<MaterialSap>().eq("MATERIAL_NO", materialNo));
    }
}
